package cn.zyx.sys.service;

import cn.zyx.common.entity.Page;
import cn.zyx.common.properites.CacheProperties;
import cn.zyx.common.utils.cache.redis.RedisUtils;
import cn.zyx.common.utils.sys.DigestsUtils;
import cn.zyx.common.utils.EncodesUtils;
import cn.zyx.common.utils.sys.UserUtils;
import cn.zyx.sys.entity.User;
import cn.zyx.sys.mapper.UserMapper;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * 用户管理
 * @author zyx
 */
@Service
@Transactional(readOnly = true)
public class UserService {

	public static final String HASH_ALGORITHM = "SHA-1";
	public static final int HASH_INTERATIONS = 1024;
	public static final int SALT_SIZE = 8;

    /**
     * -- GETTER --
     *  获取系统定义的超级用户
     *
     * @return
     */
    @Getter
    @Value("${superUser}")
	private String superUser;

	@Autowired
	private UserMapper mapper;


    /**
	 * 生成安全的密码，生成随机的16位salt并经过1024次 sha-1 hash
	 */
	public static String entryptPassword(String plainPassword) {
		byte[] salt = DigestsUtils.generateSalt(SALT_SIZE);
		// 对字符串进行散列
		byte[] hashPassword = DigestsUtils.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
		return EncodesUtils.encodeHex(salt) + EncodesUtils.encodeHex(hashPassword);
	}

	/**
	 * 验证密码
	 * @param plainPassword 明文密码
	 * @param password 密文密码
	 * @return 验证成功返回true
	 */
	public static boolean validatePassword(String plainPassword, String password) {
		byte[] salt = EncodesUtils.decodeHex(password.substring(0,16));
		System.out.println(DigestsUtils.generateSalt(SALT_SIZE));
		byte[] hashPassword = DigestsUtils.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
		System.out.println(EncodesUtils.encodeHex(salt)+EncodesUtils.encodeHex(hashPassword));
		return password.equals(EncodesUtils.encodeHex(salt) + EncodesUtils.encodeHex(hashPassword));
	}


	/**
	 * 修改保存用户信息
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void saveUser(User user) {
		if (StringUtils.isBlank(user.getId())){
			user.preInsert();
			mapper.insert(user);
		} else {
			// 清除原用户机构用户缓存
			User oldUser = mapper.get(user.getId());
			if (oldUser.getOffice() != null && oldUser.getOffice().getId() != null){
				RedisUtils.deleteObject(CacheProperties.USER_CACHE + CacheProperties.USER_CACHE_LIST_BY_OFFICE_ID_ + oldUser.getOffice().getId());
			}
			// 更新用户数据
			user.preUpdate();
			mapper.update(user);
		}
		if (StringUtils.isNotBlank(user.getId())){
			// 更新用户与角色关联
			mapper.deleteUserRole(user);
			if (user.getRoleList() != null && !user.getRoleList().isEmpty()){
				mapper.insertUserRole(user);
			} else {
				throw new RuntimeException(user.getLoginName() + "没有设置角色！");
			}
			// 清除用户缓存
			UserUtils.clearCache(user);
		}
	}

	/**
	 * 删除用户
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void deleteUser(User user) {
		mapper.deleteUserRole(user);
		mapper.delete(user);
		// 清除用户缓存
		UserUtils.clearCache(user);
	}

	/**
	 * 根据登录名获取用户
	 * @param loginName
	 * @return
	 */
	public User getUserByLoginName(String loginName) {
		return UserUtils.getByLoginName(loginName);
	}

	/**
	 * 根据id获取用户
	 * @param id
	 * @return
	 */
	public User get(String id) {
		return UserUtils.get(id);
	}

	/**
	 * 查询分页数据
	 * @param page 分页对象
	 * @param user
	 * @return
	 */
	public Page<User> findPage(Page<User> page, User user) {
		user.setPage(page); // 设置参数
		page.setCount(mapper.findPageCount(user));
		page.setList(mapper.findList(user));
		return page;
	}

	/**
	 * 更新用户登录信息
	 * @param user
	 */
	@Transactional(readOnly = false)
    public void updateUserLoginInfo(User user) {
		// 保存上次登录信息
		user.setOldLoginIp(user.getLoginIp());
		user.setOldLoginDate(user.getLoginDate());
		// 更新本次登录信息
		user.setLoginIp(UserUtils.getSession().getHost());
		user.setLoginDate(new Date());
		mapper.updateLoginInfo(user);
    }
}
